package com.foryouco.cody;

import com.foryouco.cody.Syntax.SyntaxType;
import java.util.logging.*;
import com.google.wave.api.*;
import java.util.regex.*;
import java.util.*;

@SuppressWarnings("serial")
public class CodyServlet extends AbstractRobotServlet
{
        @Override
        public void processEvents(RobotMessageBundle bundle) 
        {
                for(Event e : bundle.getEvents())
                {
                        if(e.getType() == EventType.BLIP_SUBMITTED)
                        {
                            TextView view = e.getBlip().getDocument();
                            int start = 0;
                            String[] syntaxInfo = null;
                            do
                            {
                            	syntaxInfo = Syntax.detectSyntax(view.getText(), start);
                            	if(syntaxInfo[0] != "-1")
                            	{
                            		colorSyntax(syntaxInfo[0].split(";"), view, new Range(Integer.valueOf(syntaxInfo[1]), Integer.valueOf(syntaxInfo[2])));
                            		start = Integer.valueOf(syntaxInfo[2]);
                            	}
                            }
                            while(syntaxInfo.length > 1);
                        }
                }
        }
        
        private void colorSyntax(String[] language, TextView view, Range rangeToSearch)
        {
                String blipText = view.getText().toLowerCase().substring(rangeToSearch.getStart(), rangeToSearch.getEnd());
                view.deleteAnnotations(rangeToSearch);
                List<String[][]> arrayToSearch = new ArrayList<String[][]>();
                for(String s : language)
                {
                        if(s.equalsIgnoreCase("php")) { arrayToSearch.add(Syntax.php);}
                        else if(s.equalsIgnoreCase("html")) { arrayToSearch.add(Syntax.html);}
                        else if(s.equalsIgnoreCase("javascript")) { arrayToSearch.add(Syntax.javascript);}
						else if(s.equalsIgnoreCase("vb.net")) { arrayToSearch.add(Syntax.vbnet);}
						else if(s.equalsIgnoreCase("csharp")) { arrayToSearch.add(Syntax.csharp);}
						else if(s.equalsIgnoreCase("c++")) { arrayToSearch.add(Syntax.cplusplus);}
						else if(s.equalsIgnoreCase("c")) { arrayToSearch.add(Syntax.c);}
						else if(s.equalsIgnoreCase("lolcode")) { arrayToSearch.add(Syntax.lolcode);}
                }
                
                for(String[][] searchArray : arrayToSearch)
                {
                        for(String[] word : searchArray)
                        {
                        	Pattern p = Pattern.compile(word[0]);
                            Matcher m = p.matcher(blipText.toLowerCase());
                            while(m.find() == true)
                            {
                                    Range range = new Range(m.start() + rangeToSearch.getStart(), m.end() + rangeToSearch.getStart());
                                      switch(SyntaxType.valueOf(word[1]))
                                            {
                                                    case START:
                                                    case END:
                                                    {
                                                            switch(word.length)
                                                            {
                                                                    case 3:
                                                                    {
                                                                            view.deleteAnnotations(range);
                                                                            view.setAnnotation(range, "style/color", word[2]);
                                                                            break;
                                                                    }
                                                                    case 4:
                                                                    {
                                                                            view.deleteAnnotations(range);
                                                                            view.setAnnotation(range, "style/color", word[2]);
                                                                            view.setAnnotation(range, "style/fontWeight", word[3]);
                                                                            break;
                                                                    }
                                                            }
                                                            if(word.length > 2)
                                                            {
                                                                    break;
                                                            }
                                                    }
                                                    case KEYWORD:
                                                    {
                                                            view.deleteAnnotations(range);
                                                            view.setAnnotation(range, "style/color", "rgb(0, 0, 128)");
                                                            view.setAnnotation(range, "style/fontWeight", "bold");
                                                            break;
                                                    }
                                                    case METHOD:
                                                    {
                                                            view.deleteAnnotations(range);
                                                            view.setAnnotation(range, "style/color", "rgb(0, 0, 255)");
                                                            view.setAnnotation(range, "style/fontWeight", "bold");
                                                            break;
                                                    }
                                                    case STRING:
                                                    {
                                                            if(range.getEnd() != 0)
                                                            {
                                                                    int index = 0;
                                                                    if(m.find() == true)
                                                                    {
                                                                            index = m.end();
                                                                    }
                                                                    else
                                                                    {
                                                                            index = blipText.length();
                                                                    }
                                                                    range.setEnd(index + rangeToSearch.getStart());
                                                                    view.deleteAnnotations(range);
                                                                    view.setAnnotation(range, "style/color", "rgb(128, 128, 128)");
                                                                    break;
                                                            }
                                                    }
                                                    case COMMENT:
                                                    {
                                                            int index = blipText.indexOf("\n", range.getEnd());
                                                            if(word.length == 3)
                                                            {
                                                                    int oldIndex = m.end();
                                                                    Pattern newP = Pattern.compile(word[2]);
                                                                    Matcher newM = newP.matcher(blipText);
                                                                    if(newM.find(oldIndex))
                                                                    {
                                                                            index = newM.end();
                                                                    }
                                                                    else
                                                                    {
                                                                            index = blipText.length();
                                                                    }
                                                            }
                                                            range.setEnd(index + rangeToSearch.getStart());
                                                            view.deleteAnnotations(range);
                                                            view.setAnnotation(range, "style/color", "rgb(0, 128, 0)");
                                                            break;
                                                    }
                                                    case VARIABLE:
                                                    {
                                                            view.deleteAnnotations(range);
                                                            view.setAnnotation(range, "style/color", "rgb(0, 0, 255)");
                                                            break;
                                                    }
                                                    case TAG:
                                                    {
                                                            view.deleteAnnotations(range);
                                                            view.setAnnotation(range, "style/color", "rgb(128, 0, 0)");
                                                            break;
                                                    }
                                                    case ELEMENT:
                                                    {
                                                            view.deleteAnnotations(range);
                                                            view.setAnnotation(range, "style/color", "rgb(0, 0, 255)");
                                                            break;
                                                    }
                                                    case ATTR:
                                                    {
                                                            view.deleteAnnotations(range);
                                                            view.setAnnotation(range, "style/color", "rgb(0, 0, 128)");
                                                            break;
                                                    }
                                                    case ATTRVALUE:
                                                    {
                                                            view.deleteAnnotations(range);
                                                            view.setAnnotation(range, "style/color", "rgb(128, 128, 128)");
                                                            break;
                                                    }
                                                    
                                            }
                            }

                        }
                }
        }
}
